<?php

use Avalanche\Model\ClientModel;

/**
 * Example Server provide example handle system
 *
 * @author Vitold Sedyshev
 */
class ExampleServer
{
    /**
     * Connection count
     *
     * @var int
     */
    protected $connectionCount = 0;

    /**
     * Number of connection
     *
     * @var int
     */
    protected $connectionNumber = 0;

    /**
     * Logging system
     *
     * @var array
     */
    protected $logs = array();

    /**
     * Logging system
     *
     * @param string $msg
     */
    protected function log($msg) {
        $tpl = '? - - [{date}] "? ? ?" ? ? "{msg}"';
        $params = array(
            '{date}' => date('Y-m-d H:i:s P'),
            '{msg}'  => $msg,
        );
        $log = strtr($tpl, $params);
        // echo $log . PHP_EOL;

        // Add logging
        $this->logs[] = $log;

        // Flush on each 100
        if (count($this->logs) > 10) {
            // Create
            $lines = join(PHP_EOL, $this->logs) . PHP_EOL;
            //file_put_contents('access.log', $lines);
            echo $lines;

            // Clean
            $this->logs = array();
        }
    }

    /**
     * Handle connection
     *
     * @param \Avalanche\Model\ClientModel $client
     * @return bool
     */
    public function handleAcceptConnection($client)
    {
        // Increment concurent connection count
        $this->connectionCount++;

        // Increment number of hndled connection
        $this->connectionNumber++;

        // Save logging information in logging system
        if (socket_getpeername($client->getSock(), $addr, $port)) {
            $this->log('Incoming connection from ' . $addr . ':' . $port);
        }

        return true;
    }

    /**
     * Close connection will rised
     *
     * @return bool
     */
    public function handleCloseConnection() {
        $this->connectionCount--;
    }

    /**
     * @param \Avalanche\Model\ClientModel $client
     * @return bool
     */
    public function handleReadConnection($client) {

        // logging handle connection
        $this->log('Handle read connection on ' . (int)$client->getSock());

        // Read buffer
        $requestBuffer = $client->getRequestBuffer();
        if (strpos($requestBuffer, "\r\n\r\n") === false) {
            return false;
        }

        // Handle request model
        $request = new \Avalanche\Model\RequestModel();

        // Parse request header
        $lines = explode("\n", $requestBuffer);
        $head = array_shift($lines);
        list($method, $uri, $protocol) = explode(' ', $head, 3);
        $request->setMethod($method);
        $request->setURI($uri);
        $request->setProtocol($protocol);

        // Parse headers
        $headers = array();
        foreach ($lines as $line) {
            $line = trim($line);
            if (strpos($line, ':') !== false) {
                list($name, $value) = explode(':', $line, 2);
                $request->setHeader($name, $value);
            } else {
                // ...
            }
        }

        // Generate response
        $action = new \Avalanche\Action\Index();
        $response = $action->execute($request);
        $responseBuffer = $response->get();

        // Send response
        $client->writeResponseBuffer($responseBuffer);

        return true;
    }

}
